#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
#define NUM 1024
#define OPT_NUM 64
char lineCommand[NUM];
char* myargv[OPT_NUM];//指针数组 用于存放切割的命令
int lastCode = 0;
int lastSig = 0;
int main()
{
    while(1)
    {
        //输出提示符
        printf("%s@%s %s# ",getenv("USER"),getenv("HOSTNAME"),getenv("PWD"));
        //sleep(1);
        
        fflush(stdout);
        //获取用户输入
        char *s = fgets(lineCommand, sizeof(lineCommand)-1,stdin);
        assert(s != NULL);

        //消除输入时候缓冲区里面的\n
        lineCommand[strlen(lineCommand)-1] = 0;
        //printf("test:%s\n",lineCommand);
            
        //字符串切割
        myargv[0] = strtok(lineCommand," ");
        int i = 1;
        if(myargv[0] != NULL && strcmp(myargv[0],"ls")==0)
        {
            myargv[i++] = (char*)"--color=auto";
        }
        while(myargv[i++] = strtok(NULL," "));
        //如果执行cd命令，就不用创建子进程，而是让shell自己执行,本质是系统调用接口 
        //像cd echo这种就是内建命令/内置命令
        if(myargv[0] != NULL && strcmp(myargv[0] , "cd") == 0)
        {
            if(myargv[1] != NULL) chdir(myargv[1]);
            continue;
        }

        if(myargv[0]!=0 && strcmp(myargv[0],"echo") == 0 && myargv[1] != 0)
        {
            if(strcmp(myargv[1],"$?") == 0)
            {
                printf("%d\n",lastCode);
            }
            else
            {
                printf("%s\n",myargv[1]);
            }
            continue;
        }
    //条件编译
#ifdef DEBUG
    for(int i = 0;myargv[i];i++)
    {
        printf("myargv[%d]:%s\n",i,myargv[i]);
    }
#endif
    
        //派发子进程执行命令
        pid_t id = fork();
        assert(id != -1);

        if(id == 0)
        {
            execvp(myargv[0],myargv);
            exit(1);
        }
        int status = 0;
        int ret = waitpid(id,&status,0);
        if(ret > 0)
        {
            lastCode = (status>>8) & 0xFF;
            lastSig = status & 0x7F;
        }
    }
    return 0;
}
